Skip to content

DOC-7226 Move the Rust use cases to redis-rs 1.8 - #4378

Merged
andy-stark-redis merged 3 commits into
mainfrom
DOC-7226-rust-use-cases
Oct 30, 2026
Merged

andy-stark-redis merged 3 commits into
mainfrom
DOC-7226-rust-use-cases

Conversation

@andy-stark-redis

@andy-stark-redis andy-stark-redis commented Oct 29, 2026 •

Copy link
Copy Markdown
Contributor

Fourth slice of DOC-7226 (deprecated client API calls in example code): move the Rust use cases to redis-rs 1.x.

Changes

  • All 13 Rust use-case demos now depend on redis = "1.8" (they pinned 0.24 or 0.27), matching the clients/rust pages. Two lockfiles (job-queue, semantic-cache) are updated.
  • session-store and time-series-dashboard open their shared connection with get_multiplexed_async_connection() and hold a MultiplexedConnection, instead of the removed non-multiplexed get_async_connection() / aio::Connection. leaderboard already did this.
  • API renames the compiler found: Value::Data/Bulk/Status became BulkString/Array/SimpleString; query_async and invoke_async take one generic; ErrorKind::TypeError became UnexpectedReturnType; ResponseError became Server(ServerErrorKind::ResponseError); borrowed values go through from_redis_value_ref; scan iterators yield results; AsyncCommands needs Send + Sync.
  • Two behavior changes that only running the demos revealed:
    • hget takes one field in 1.x (the old one silently sent HMGET for several), so multi-field reads in feature-store and recommendation-engine use hmget.
    • 1.x puts a 500 ms response timeout on every connection manager and multiplexed connection. job-queue (BLMOVE) and streaming (XREADGROUP ... BLOCK) failed with "timed out" until their managers were built with ConnectionManagerConfig::new().set_response_timeout(None).
  • time-series-dashboard: as_f64 now accepts SimpleString and Double. The dashboard's /api/snapshot already failed on main against Redis 8.10.2, because RESP2 time series doubles arrive as simple strings.
  • The _index.md pages: updated Cargo.toml snippets, the same API changes in the embedded code, the Rust minimum (redis 1.8 requires Rust 1.88, so the pages' 1.70, 1.74 and 1.75 were wrong), and prose that named the old versions. The "not typed on 0.27" / "no typed XAUTOCLAIM on 0.24" statements are corrected (1.8 has typed hexpire, httl, hpersist and xautoclaim_options; the demos still use the generic builder, which works). The prefetch-cache sentence about a bare redis::aio::Connection now describes MultiplexedConnection, which is Clone but does not reconnect.

Verification

  • All 13 demos compile on redis 1.8.0 (cargo check --all-targets), with no deprecation warnings.
  • Each demo was built and run against Redis 8.10.2 and exercised through its HTTP endpoints: cache-aside, prefetch-cache, leaderboard, rate-limiter, session-store (full cookie flow), time-series-dashboard, feature-store, streaming, job-queue, pub-sub, recommendation-engine, and the two candle-based demos semantic-cache and memory-layer (embedding, write, recall, cache hit).
  • The page snippets were edited to mirror the .rs files; they were not compiled separately.

Not verified

  • Nothing was tested on redis 1.0.4 to 1.7, and no demo was run against a cluster or Sentinel.
  • Bugbot and review have not seen the second commit yet.

🤖 Generated with Claude Code


Note

Medium Risk
Wide mechanical migration across many demos with a few runtime behavior changes (blocking timeouts, HMGET, RESP parsing); example/docs code only, but incorrect timeouts or parsing would break the interactive demos.

Overview
All 13 Rust use-case demos now pin redis = "1.8" (replacing 0.24/0.27), with Cargo.lock updates where present and matching changes in the _index.md snippets, prerequisites (Rust 1.88), and prose about typed commands and cluster doc links.

Code updates for redis-rs 1.x API: single-type query_async/invoke_async, from_redis_value_ref, renamed Value variants (BulkString, Array, etc.), ErrorKind::UnexpectedReturnType and Server(ServerErrorKind::ResponseError), explicit hmget for multi-field reads, Send + Sync on async connection bounds, and ? on SCAN iterator items.

Behavior fixes tied to 1.8: job-queue and streaming build ConnectionManager with set_response_timeout(None) so BLMOVE / XREADGROUP ... BLOCK are not cut off by the default 500 ms timeout; session-store and time-series-dashboard use get_multiplexed_async_connection() / MultiplexedConnection; time-series-dashboard parses RESP2 doubles from SimpleString / Double so snapshots work on newer Redis.

Reviewed by Cursor Bugbot for commit 9dad069. Bugbot is set up for automated code reviews on this repo. Configure here.

… time-series-dashboard and rate-limiter use cases

The session-store and time-series-dashboard demos opened their shared connection with
Client::get_async_connection() and held it as redis::aio::Connection. That non-multiplexed
connection is gone from Client in redis-rs 1.x, and the leaderboard use case, which pins the
same 0.24 crate, already uses get_multiplexed_async_connection() and MultiplexedConnection.
Both demos and the session-store page snippet now do the same, and the rate-limiter page's
async snippet names MultiplexedConnection instead of the removed type. The change is
forward-compatible: both APIs exist in 0.24 and 1.x, so the crate pins are unchanged.

Both demos build against redis 0.24.1. The session-store demo was run against Redis 8.10.2
and passed login, session read, increment and logout. The time-series-dashboard demo writes
its samples, but its /api/snapshot endpoint returns a parse error that the unmodified demo
on main returns identically, so it is not caused by this change.

Learned: of the use cases that looked affected by redis-rs 1.x, only session-store and time-series-dashboard used the removed non-multiplexed connection in code; the others already use ConnectionManager or MultiplexedConnection
Directive: keep these demos on get_multiplexed_async_connection(), which works on the 0.24 pins and on 1.x; do not reintroduce get_async_connection()
Recheck: when the Rust use cases move to redis-rs 1.x, rerun the time-series-dashboard snapshot, which fails to parse f64 from a status reply on 0.24.1 against Redis 8.10.2
Gaps: the crate pins were not bumped, nothing was compiled against 1.x, and the prefetch-cache page still says a bare redis::aio::Connection is not Clone, which names a type that no longer exists in 1.x
Ticket: DOC-7226
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
@github-actions

github-actions Bot commented Oct 29, 2026 •

Copy link
Copy Markdown
Contributor

DOC-7226

@github-actions

github-actions Bot commented Oct 29, 2026 •

Copy link
Copy Markdown
Contributor

🧠 Redis Memory

Found 11 related items from repository history (5 new this commit):

Memory updated at 9dad069

@dwdougherty dwdougherty left a comment •

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fourth slice? I can haz 🥧? Approved.

@andy-stark-redis

Copy link
Copy Markdown
Contributor Author

Can haz fourth slice @dwdougherty :-) Kthxbai.

All 13 Rust use-case demos now depend on redis 1.8 (they pinned 0.24 or 0.27), matching the
clients/rust pages, and the use-case pages are updated to match. Compiling cleared most of it:
Value::Data, Bulk and Status became BulkString, Array and SimpleString; query_async and
invoke_async take one generic; ErrorKind::TypeError became UnexpectedReturnType and
ResponseError became Server(ServerErrorKind::ResponseError); borrowed values go through
from_redis_value_ref; scan iterators yield results; AsyncCommands needs Send + Sync.

Two changes only running the demos could find. hget takes one field in 1.x (the old one
silently sent HMGET for several), so multi-field reads use hmget. And 1.x puts a 500 ms
response timeout on every connection manager and multiplexed connection, so the job-queue
BLMOVE workers and the streaming XREADGROUP BLOCK consumers failed with "timed out" until
their managers were built with the response timeout removed.

I also fixed the time-series dashboard's as_f64 helper, which already failed on main against
a current server: RESP2 time series doubles arrive as simple strings and the helper only
accepted integers and bulk strings.

Every demo was built and run against Redis 8.10.2 and exercised through its HTTP endpoints,
including the two candle-based demos with the cached MiniLM model. The pages now state the
Rust 1.88 minimum that redis 1.8 requires, and the prefetch-cache page no longer describes the
removed non-multiplexed connection. Bugbot and review have not seen this commit yet.

Learned: redis-rs 1.x applies a 500 ms response timeout to every ConnectionManager and multiplexed connection, so blocking commands such as BLMOVE and XREADGROUP BLOCK fail with "timed out" at runtime while the code still compiles
Constraint: demos that block on the server (job-queue, streaming) must build their ConnectionManager with ConnectionManagerConfig::new().set_response_timeout(None)
Directive: use hmget for several hash fields; hget takes exactly one field in redis-rs 1.x
Recheck: the crate is declared as 1.8 and needs Rust 1.88; if the pages' stated Rust minimum or the redis version changes, update all 13 pages together
Gaps: nothing was tested against redis 1.0.4 to 1.7, the page snippets were edited to mirror the .rs files but not compiled, and the demos were not run against a cluster or Sentinel
Ticket: DOC-7226
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
@CLAassistant

CLAassistant commented Oct 30, 2026 •

Copy link
Copy Markdown

CLA assistant check
All committers have signed the CLA.

@andy-stark-redis andy-stark-redis changed the title DOC-7226 Use multiplexed async connections in the Rust use cases DOC-7226 Move the Rust use cases to redis-rs 1.8 Oct 30, 2026

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes using high effort and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, have a team admin enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 51fde74. Configure here.

let mut ids: Vec<String> = Vec::new();
let prefix_len = self.key_prefix.len();
while let Some(k) = iter.next_item().await {
let k = k?;

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

SCAN count ignores iterator errors

Medium Severity

count_entities still treats every next_item() yield as a key. In redis-rs 1.8 that method returns Option<RedisResult<T>>, so a SCAN error is counted as an entity and never returned. The same file already unwraps the Result in list_entity_ids and reset.

Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 51fde74. Configure here.

count_entities looped over the scan iterator with while let Some(_k) and never looked at the
item. In redis-rs 1.x next_item yields Option<RedisResult<T>>, so a SCAN error was counted as
an entity and never returned. Bugbot caught it. The compiler could not, because a pattern that
discards the item type-checks under both versions. The loop now propagates the error, like the
other two scan loops in the file.

Checked every other next_item loop in the Rust use cases; the only other two (prefetch-cache)
already propagate the error. The feature-store demo still reports 200 entities.

Learned: after a redis-rs 1.x bump, a loop that discards the item (while let Some(_k) = iter.next_item()) compiles unchanged but silently counts scan errors as items, so grep every next_item loop instead of relying on compiler errors
Ticket: DOC-7226
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants